//@include I1

   //@include   I2

var START_DATE = "STARTDATE";
var END_DATE = "ENDDATE";
var USER_ID = "USER_ID";
var JSON_FROM = "d_from";
var JSON_TO = "d_to";
var TABLE_FROM = "from";
var TABLE_TO = "to";
var TABLE_LONGDATE = "longDate";
var TABLE_SUBTYPE = "subType";
var EVENTS = "events";
var TRANSACTIONS = "transactions";
var CONTRACT_ID = "contractId";
var TABLE_REF_ID = "refId";
//var found = false;
var started = false;


function main( ui ) {

  //return getAppointmentsTEST( jsonObject );
 // return getAppointmentsTEST( );
  
  var json = ui.getQueryParameters().getFirst("json");
  if ( json == null ){
        var ex = "{ exception: { message: 'no param provided'} }";
        return ex;
  }
  var jsonObject = new JSONObject( json );
  
  var cal1 = java.util.Calendar.getInstance();
  
  cal1.setTimeInMillis(jsonObject.get(START_DATE));
  var d = cal1.get(java.util.Calendar.DAY_OF_MONTH)+1;
  var m = cal1.get(java.util.Calendar.MONTH);
  var y = cal1.get(java.util.Calendar.YEAR);
  var h = cal1.get(java.util.Calendar.HOUR_OF_DAY);
  var mi = cal1.get(java.util.Calendar.MINUTE);
  //return "day=" + d + " month=" + m + " year=" + y + " hour=" + h + " minutes=" + mi; 
  var filteredTransactions = getFilteredTransactions(jsonObject);
  var filteredEvents = getFilteredEvents(jsonObject);
  
  var result = new JSONObject();
  result.put (EVENTS,filteredEvents);
  result.put (TRANSACTIONS,filteredTransactions);
  return validateTransactions(result);
 // return result.toString();
}

function validateTransactions(json){
  
  var finalEvents = new JSONArray();
  var finalTransactions = new JSONArray();
  var events = json.get(EVENTS);
  var transactions = json.get(TRANSACTIONS);
  var contractId;
  var eventObj;
  var transactionObj;
  //var found = new Array();
  //found[0]=false;
 // found = false;
  for ( var i = 0; i< events.length(); i++ ){
   /*
    found = false;  
    if ( !found){
           finalEvents.put( eventObj);
       }
     */
      eventObj = events.get(i);
      contractId = eventObj.get(CONTRACT_ID);
      var found = false;
      for ( var y = 0; y < transactions.length(); y++ ){
          //found[0]=true;
          
          if ( transactions.get(y).get(TABLE_REF_ID).equals(contractId)){
             // break;
              if ( transactions.get(y).get(TABLE_SUBTYPE).equals('in' ) ){
                  var transactionObjIn = transactions.get(y);
                  var isValid = compareEventsVsTransactions(eventObj,transactionObjIn);
                
                  if ( !isValid ){
                      finalEvents.put( eventObj);
                      break;  
                  }
              }
    
            else if ( transactions.get(y).get(TABLE_SUBTYPE).equals('out' ) ){
                  var transactionObjOut = transactions.get(y);
                  var isValid = compareEventsVsTransactions(eventObj,transactionObjOut);
        
                  if ( !isValid ){
                     finalEvents.put( eventObj);
                     break;  
                  }
              } else if (  !found ) {
              finalEvents.put( eventObj);
              } else continue;
          }
     } 
    
        
    }
 
    var finalResult = new JSONObject();
    finalResult.put(EVENTS, finalEvents);
    return finalResult.toString();
   
  }
  

function distance(lat1, lon1, lat2, lon2, unit) {
  var radlat1 = Math.PI * lat1/180;
  var radlat2 = Math.PI * lat2/180;
  var radlon1 = Math.PI * lon1/180;
  var radlon2 = Math.PI * lon2/180;
  var theta = lon1-lon2;
  var radtheta = Math.PI * theta/180;
  var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
  dist = Math.acos(dist);
  dist = dist * 180/Math.PI;
  dist = dist * 60 * 1.1515;
  if (unit=="K") { dist = dist * 1.609344; }
  if (unit=="N") { dist = dist * 0.8684; }
  return dist < unit;
}                                                       


function compareEventsVsTransactions(eventObj,transaction){
  var subType = transaction.get(TABLE_SUBTYPE);
  var tollerance = 10 * 60 * 1000;
  
  return false;
  if ( subType.equals('in')){
      var eventFrom = eventObj.get(TABLE_FROM);
      var badgeIn = transaction.get(TABLE_LONGDATE);
      var deltaFrom = eventFrom - badgeIn > 0 ? (eventFrom - badgeIn) : (badgeIn - eventFrom);
  
      return deltaFrom > tollerance ;
   
       } else {
       
      var eventTo = eventObj.get(TABLE_TO);
      var badgeOut = transaction.get(TABLE_LONGDATE);
      var tollerance = 10 * 60 * 1000;
  
      var deltaTo = eventTo - badgeOut > 0 ? (eventTo - badgeOut) : (badgeOut - eventTo);
  
      return deltaTo > tollerance;
    
       }
       
    }
  


function getAppointmentsTEST() {

  var records = new JSONArray();
  
   var o = new JSONObject( );
   
   var cal1 = java.util.Calendar.getInstance();
   cal1.set( 2011, 1, 20 );
  
   o.put("d_from", cal1.getTime() );

  var cal2 = java.util.Calendar.getInstance();
  
  cal2.set( 2011, 4, 25 );
  o.put("d_from1", cal2.getTime() );
  
  o.put("userId","casolla.alessandro@gmail.com")
  
  //return o.toString();
  //var cmd = "select t from EventEntity t where t.from > :d_from and t.from < :d_from1";
    // var cmd = "select t from EventEntity t where t.userId = :userId";
 var cmd = "select t from EventEntity t where t.userId = :userId and t.from > :d_from and t.from < :d_from1 order by t.from asc";
   // var cmd = "select t from EventEntity t where t.userId = :userId";
  // var cmd = "select t from EventEntity t where t.from > :d_from and t.from < :d_from1";
    EntityManager.find(  
    cmd,  
     o,
     function(result) {
      
      for( var i = 0; i < result.size() ; ++i ) {
        
        records.put( JSONObject.wrap(result.get(i)) );
      }
      
    });
    
    var result = new JSONObject();
    
    result.put( "records", records );
    

   // return result.toString() ;
    return records;
}


function getFilteredEvents(jsonObject) {
  
  var records = new JSONArray();
  
 var json = createEventJsonFilter(jsonObject);
 var cmd = createEventCmd(jsonObject);
    EntityManager.find(  
    cmd,  
    json,
     function(result) {
      
      for( var i = 0; i < result.size() ; ++i ) {
        
        records.put( JSONObject.wrap(result.get(i)) );
      }
      
    });
    
    var result = new JSONObject();
    
    result.put( "records", records );
    
    //return result.toString() ;
    return records;
}


function getFilteredTransactions(jsonObject) {
  
  var records = new JSONArray();
  
 var cmd = "select t from TransactionEntity t where t.longDate > :STARTDATE and t.longDate < :ENDDATE";
    EntityManager.find(  
    cmd,  
    jsonObject,
     function(result) {
      
      for( var i = 0; i < result.size() ; ++i ) {
        
        records.put( JSONObject.wrap(result.get(i)) );
      }
      
    });
    
    var result = new JSONObject();
    
    result.put( "records", records );
    
    return records ;

}

function createEventJsonFilter(jsonObject){

  var o = new JSONObject();   
  var attributes;
  var title;
  var userId;
 /*
  if (jsonObject.has('attributes')) 
      attributes = jsonObject.get('attributes');
  
  if ( attributes.has('title')){
      title = attributes.get('title');
      o.put('title',title);
  }
  */
  
  if (jsonObject.has(USER_ID)) {
      userId = jsonObject.get(USER_ID);
      o.put('userId',userId);
  }
  
  var cal1 = java.util.Calendar.getInstance();
  cal1.setTimeInMillis(jsonObject.get(START_DATE));
  var d1 = cal1.get(java.util.Calendar.DAY_OF_MONTH)+1;
  var m1 = cal1.get(java.util.Calendar.MONTH);
  var y1 = cal1.get(java.util.Calendar.YEAR);
  cal1.set( y1, m1, d1,0,0 );
  
  var startDate = cal1.getTime();
  
  var cal2 = java.util.Calendar.getInstance();
  cal2.setTimeInMillis(jsonObject.get(END_DATE));
  var d2 = cal2.get(java.util.Calendar.DAY_OF_MONTH)+1;
  var m2 = cal2.get(java.util.Calendar.MONTH);
  var y2 = cal2.get(java.util.Calendar.YEAR);
  cal2.set( y2, m2, d2,23,59 );
  
  var endDate = cal2.getTime();
    
  o.put(JSON_FROM, startDate);
  o.put(JSON_TO,endDate);
  
  return o;
}

function createEventCmd(jsonObject){

  var cmd = "select t from EventEntity t where t.from > :d_from and t.from < :d_to";
 /*
  if ( jsonObject.has('contractId'))
    cmd += " and t.contractId = :contractId";

  if ( jsonObject.has('USER_ID'))
    cmd += " and t.userId = :userId";
*/
  return cmd;
}
